package com.adcc.ags.gms.mq.controller;

import com.adcc.ags.gms.core.util.Constant;
import com.adcc.ags.gms.core.util.LogFactory;
import com.adcc.ags.gms.core.vo.ResultState;
import com.adcc.ags.gms.core.vo.ResultVO;
import com.adcc.ags.gms.mq.entity.Queue;
import com.adcc.ags.gms.mq.service.QueueService;
import com.adcc.ags.gms.mq.vo.QueueVO;
import com.adcc.ags.gms.user.entity.GWUser;
import com.adcc.ags.gms.user.service.GWUserService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;

/**
 * 用户队列控制层
 */
@Controller
@RequestMapping(value="/UserQueue",produces = MediaType.APPLICATION_JSON_VALUE)
public class UserQueueController {

    @Autowired
    private LogFactory log;

    @Autowired
    private QueueService mqService;

    @Autowired
    private GWUserService userConfigService;

    /**
     * 根据队列名称查询用户队列
     * @param name
     * @param currentPage
     * @param pageSize
     * @return
     */
    @RequestMapping(value = "/findUserQueueByName", method = RequestMethod.GET)
    public @ResponseBody ResultVO findUserQueueByName( String name, int currentPage,int pageSize){
        ResultVO resultVO = new ResultVO();
        try {
            PageHelper.startPage(currentPage, pageSize);
            Optional<PageInfo<Queue>> optional = mqService.findUserQueueByName(name, currentPage, pageSize);
            if(optional.isPresent()){
                resultVO.setPageInfo(optional.get());
                if(optional.get().getList().size() > 0){
                    List<QueueVO> list = Lists.newArrayListWithExpectedSize(100);
                    for(Queue queue : optional.get().getList()){
                        QueueVO vo = new QueueVO(queue);
                        list.add(vo);
                    }
                    resultVO.getData().put("queueVO",list);
                }
            }else {
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
            return resultVO;
        } catch (Exception ex) {
            log.error(UserQueueController.class,"findUserQueueByName() error",ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
            return resultVO;
        }
    }

    /**
     * 校验队列名称
     * @param queueName
     * @return
     */
    @RequestMapping(value = "/checkQueueName", method = RequestMethod.GET)
    public @ResponseBody ResultVO checkQueueName(@RequestParam("queueName")String queueName) {
        ResultVO resultVO = new ResultVO();
        try{
            String strQueueName = Strings.nullToEmpty(queueName);
            Optional<Boolean> optional = mqService.isExistQueueName(strQueueName);
            if (optional.isPresent()) {
                if(optional.get()){
                    resultVO.setCode(0);
                    resultVO.setState(ResultState.FAILURE);
                    resultVO.setReason("队列名已存在");
                }
            }else{
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
            return resultVO;
        }catch (Exception ex){
            log.error(UserQueueController.class, "checkQueueName() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
            return resultVO;
        }
    }

    /**
     * 创建用户队列
     * @param vo
     * @return
     */
    @RequestMapping(value ="/{id}",method = RequestMethod.POST)
    public @ResponseBody ResultVO createQueue(@PathVariable("id") long id,QueueVO vo) {
        ResultVO resultVO = new ResultVO();
        try {
            Optional<Boolean> optional = mqService.createQueue(vo);
            if (!optional.isPresent()) {
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
        } catch (Exception ex) {
            log.error(UserQueueController.class,"createQueue() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }

    /**
     * 修改用户队列
     * @param vo
     * @return
     */
    @RequestMapping(value ="/{id}",method = RequestMethod.PUT)
    public @ResponseBody ResultVO updateQueue(@PathVariable("id") long id,@RequestBody QueueVO vo) {
        ResultVO resultVO = new ResultVO();
        try {
            Optional<Boolean> optional = mqService.updateQueue(vo);
            if (!optional.isPresent()) {
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
        } catch (Exception ex) {
            log.error(UserQueueController.class,"updateQueue() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }

    /**
     * 删除用户队列
     * @param id
     * @param session
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public @ResponseBody ResultVO deleteQueue(@PathVariable("id") Long id, HttpSession session) {
        ResultVO resultVO = new ResultVO();
        try {
            Optional<Boolean> optional = mqService.deleteQueue(id);
            if(!optional.isPresent()){
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_DB_ERROR);
            }
        } catch (Exception ex) {
            log.error(UserQueueController.class,"deleteQueue() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }

    /**
     * 用户队列生效
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/onEnable", method = RequestMethod.POST)
    public @ResponseBody ResultVO onEnable(@PathVariable("id") long id) {
        ResultVO resultVO = new ResultVO();
        try {
            Optional<Boolean> optional = mqService.onEnable(id);
            if (optional.isPresent()) {
                if(!optional.get()){
                    resultVO.setCode(-1);
                    resultVO.setState(ResultState.FAILURE);
                    resultVO.setReason("用户队列不存在");
                }
            }else{
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason("用户队列生效失败");
            }
        } catch (Exception ex) {
            log.error(UserQueueController.class,"onEnable() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }

    /**
     * 用户队列失效
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/onDisable", method = RequestMethod.POST)
    public @ResponseBody ResultVO onDisable(@PathVariable("id") long id) {
        ResultVO resultVO = new ResultVO();
        try {
            List<GWUser> list = userConfigService.findByQueueId(Long.valueOf(id));
            if(list == null || list.size() == 0){
                Optional<Boolean> optional = mqService.onDisable(id);
                if (optional.isPresent()) {
                    if(!optional.get()){
                        resultVO.setCode(-1);
                        resultVO.setState(ResultState.FAILURE);
                        resultVO.setReason("用户队列不存在");
                    }
                }else{
                    resultVO.setCode(-1);
                    resultVO.setState(ResultState.FAILURE);
                    resultVO.setReason("用户队列生效失败");
                }
            }else{
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason("用户队列已关联用户");
            }
        } catch (Exception ex) {
            log.error(UserQueueController.class,"onDisable() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }

    /**
     * 分析比较当前队列与目标队列
     * @return
     */
    @RequestMapping(value = "/analyzeSyncQueue", method = RequestMethod.GET)
    public @ResponseBody ResultVO analyzeSyncQueue() {
        ResultVO resultVO = new ResultVO();
        try{
            Optional<Map<String,List<QueueVO>>> optional = mqService.analyzeSyncQueue();
            if(optional.isPresent()){
                resultVO.setData(optional.get());
            }else{
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason(Constant.GMS_SERVER_ERROR);
            }
            return resultVO;
        }catch (Exception ex){
            log.error(UserQueueController.class, "analyzeSyncQueue() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
            return resultVO;
        }
    }

    /**
     * 同步队列
     * @param newQueue
     * @param diffQueue
     * @return
     */
    @RequestMapping(value = "/synQueue", method = RequestMethod.POST)
    public @ResponseBody ResultVO synQueue(String newQueue,String diffQueue) {
        ResultVO resultVO = new ResultVO();
        try{
            List<QueueVO> newList = Lists.newArrayListWithExpectedSize(1000);
            List<QueueVO> diffList = Lists.newArrayListWithExpectedSize(1000);
            if(!Strings.isNullOrEmpty(newQueue)){
                List<Map<String,Object>> list = new ObjectMapper().readValue(newQueue,List.class);
                for (Map<String,Object> map : list){
                    QueueVO vo = new QueueVO();
                    vo.setName(map.get("name").toString());
                    vo.setType(Integer.valueOf(map.get("type").toString()));
                    vo.setPriority(Integer.valueOf(map.get("priority").toString()));
                    vo.setPersistent(Boolean.valueOf(map.get("persistent").toString()));
                    vo.setMaxDepth(Integer.valueOf(map.get("maxDepth").toString()));
                    vo.setMaxMsgLength(Integer.valueOf(map.get("maxMsgLength").toString()));
                    vo.setRetainInterval(Integer.valueOf(map.get("retainInterval").toString()));
                    vo.setEnable(true);
                    newList.add(vo);
                }
            }
            if(!Strings.isNullOrEmpty(diffQueue)){
                List<Map<String,Object>> list = new ObjectMapper().readValue(diffQueue, List.class);
                for (Map<String,Object> map : list){
                    QueueVO vo = new QueueVO();
                    vo.setName(map.get("name").toString());
                    vo.setType(Integer.valueOf(map.get("type").toString()));
                    vo.setPriority(Integer.valueOf(map.get("priority").toString()));
                    vo.setPersistent(Boolean.valueOf(map.get("persistent").toString()));
                    vo.setMaxDepth(Integer.valueOf(map.get("maxDepth").toString()));
                    vo.setMaxMsgLength(Integer.valueOf(map.get("maxMsgLength").toString()));
                    vo.setRetainInterval(Integer.valueOf(map.get("retainInterval").toString()));
                    vo.setEnable(true);
                    diffList.add(vo);
                }
            }
            Optional<Boolean> optional = mqService.syncQueue(newList, diffList);
            if (!optional.isPresent()) {
                resultVO.setCode(-1);
                resultVO.setState(ResultState.FAILURE);
                resultVO.setReason("队列同步至MQ Server失败");
            }
        }catch (Exception ex){
            log.error(UserQueueController.class, "synQueues() error", ex);
            resultVO.setCode(-1);
            resultVO.setState(ResultState.FAILURE);
            resultVO.setReason(Constant.GMS_SERVER_ERROR);
        }
        return resultVO;
    }
}
